﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;

using System.Text;
using WHLRDF.ORM.EF;

namespace WHLRDF.ORM
{
    /// <summary>
    /// EF 实例类型
    /// </summary>
    public enum EFDbType { 
        /// <summary>
        /// 默认
        /// </summary>
        Default,
        /// <summary>
        /// 只读查询
        /// </summary>
        Query,
        /// <summary>
        /// 安装实例
        /// </summary>
        Install
    }
    public class EFRepository : IDbRepository
    {
        public DbContext Current {
            get {
                return _provider.Database;
            }
        }
        private ProviderType _ProviderType { get; set; }

        public string DbVersion { get; set; }

        public ProviderType DbProviderType { get => _ProviderType; }

        private Provider<AbstractDbContext> _provider { get; set; }
        public bool AutoOpenClose
        {
            get
            {
                return _provider.Database.AutoOpenClose;
            }
        }
        /// <summary>
        /// 初始化数据库
        /// </summary>
        /// <returns></returns>
        public bool DbEnsureCreated()
        {
           return _provider.Database.DbEnsureCreated();
        }
        ~EFRepository() {
            //this.Close();
        }
        public EFRepository()
        {
            var dbversion = ApplicationEnvironments.Site.ProviderVersion;
            var dbtype = Type.GetType($"{this.GetType().Namespace}.{ApplicationEnvironments.Site.ProviderType.ToString()}.EFDataAccess,{this.GetType().Namespace}.{ApplicationEnvironments.Site.ProviderType.ToString()}");
            _provider = CreateInstance(dbtype, ApplicationEnvironments.Site.ConnectionString, dbversion);
           

        }
        public EFRepository(Type dataInstanceType, string conntionString,string dbVersion)
        {
            _provider = CreateInstance(dataInstanceType, conntionString, dbVersion,null);
         
        }

        public EFRepository(Type dataInstanceType, string conntionString,string dbVersion, object argDbModels)
        {
            _provider = CreateInstance(dataInstanceType, conntionString, dbVersion, argDbModels);
         
        }
        public EFRepository(Provider<AbstractDbContext> provider)
        {
            this.Init(provider);
        }
        private void Init(Provider<AbstractDbContext> provider)
        {
            _provider.Database = provider.Database;
          
            _ProviderType = provider.Database.DbProviderType;
         
        }
        public Provider<AbstractDbContext> CreateInstance(Type dataInstanceType, string conntionString,string dbVersion)
        {
            return this.CreateInstance(dataInstanceType, conntionString, dbVersion,null);
        }
        private Provider<AbstractDbContext> CreateInstance(Type dataInstanceType, string conntionString,string dbVersion, object argDbModels)
        {
            List<object> args = new List<object>();
            if (argDbModels != null)
            {
                args.Add(argDbModels);
            }
            args.Add(dbVersion);
            _provider = ProviderFactory.CreateProvider<AbstractDbContext>(conntionString, dataInstanceType, dbVersion, args);
            DbVersion = dbVersion;
            Init(_provider);
            return _provider;
        }
        #region Execute
     
        public IDbTransaction Begin()
        {
            return _provider.Database.Begin();
        }
        public void Commit()
        {
            _provider.Database.Commit();
        }
        public void Rollback()
        {
            _provider.Database.Rollback();
        }
        public int Execute(string sqlCommand)
        {
            return _provider.Database.ExecuteNonQuery(sqlCommand);
        }


        public int Execute(string sqlCommand, DataParameterCollection parametersValues) {
            return _provider.Database.ExecuteNonQuery(sqlCommand, parametersValues!=null?parametersValues.ToArray():null);
        }

        public int ExecuteProcedure(string procedureName)
        {
            return _provider.Database.ExecuteProcedure(procedureName, null);
        }

        public int ExecuteProcedure(string procedureName,DataParameterCollection dbParameters)
        {
            return _provider.Database.ExecuteProcedure(procedureName, dbParameters != null ? dbParameters.ToArray() : null);
        }
        #endregion
        public TEntity GetById<TEntity>(string id) where TEntity : class, new()
        {
            return GetById<TEntity>(id,null,true);
        }

        public TEntity GetById<TEntity>(string id,Func<TEntity, TEntity> func) where TEntity : class, new()
        {
            return GetById<TEntity>(id, func, true);
        }
        public TEntity GetById<TEntity>(string id, Func<TEntity, TEntity> func, bool isCache=true) where TEntity : class, new()
        {
            if (id == null || string.IsNullOrWhiteSpace(id))
            {
                return default(TEntity) ;
            }
            TEntity entity = null;
            DataProxy dataProxy = new DataProxy(typeof(TEntity));
            DataParameterCollection dataparam = new DataParameterCollection(this);
            ICriterion criterion = Expression.Eq(dataProxy.PrimaryKeyName, id);
            string sql = string.Format(_provider.Database.GetSelectSql(dataProxy.TableName, dataProxy.QueryFieldBuilder, dataProxy.TableAttr.IsDeleted), " and " + criterion.ToString(ref dataparam));
            var idataReader = this.Reader(sql, dataparam);

            try
            {
                if (idataReader.Read())
                {
                    entity = dataProxy.DataReaderToEntity<TEntity>(idataReader);
                }
                if (entity != null && func != null)
                {
                    entity = func(entity);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
              //  idataReader.Close();
            }
            return entity;
            // dbContext.Remove();
        }

        
        public TEntity Select<TEntity>(ICriterion criterion) where TEntity : class, new()
        {
            var list = this.Query<TEntity>(criterion, null);
            if (list != null && list.Count > 0)
            {
                return list[0];
            }
            return null;
        }

        public TEntity Select<TEntity>(string hql, ICriterion criterion) where TEntity : class, new()
        {
            var list = this.Query<TEntity>(hql, criterion);
            if (list != null && list.Count > 0)
            {
                return list[0];
            }
            return null;
        }

        public bool Delete<TEntity>(TEntity entity) where TEntity : class,new()
        {
            DataProxy dataProxy = new DataProxy(typeof(TEntity));
            return this.Delete<TEntity>(entity,dataProxy);
        }

        public bool Delete<T>(T entity, DataProxy dataProxy) where T : class, new()
        {
            object id = dataProxy.GetPrimaryValue(entity);
            ICriterion criterion = Expression.Eq(dataProxy.PrimaryKeyName, id);
            var dataparam = new DataParameterCollection(this);
            string sql = string.Format(dataProxy.DeleteSql(ref dataparam), " and " + criterion.ToString(ref dataparam));
            int i = this.Execute(sql, dataparam);
            return i > 0;
        }
        public bool Delete<T>(ICriterion criterion, bool isupdated=true) where T : class, new()
        {
            DataProxy dataProxy = new DataProxy(typeof(T));

            DataParameterCollection dataParam = new DataParameterCollection(this);
            string where = criterion.ToString(ref dataParam);
            if (string.IsNullOrWhiteSpace(where))
            {
                throw new Exception("没有相关查询条件！");
            }

            int i = this.Execute(string.Format(dataProxy.DeleteSql(ref dataParam) ," and " + where), dataParam);

            return i > 0;
        }

        
        public bool Delete<T>(string ids, bool isupdated=true) where T : class, new()
        {
            DataProxy dataProxy = new DataProxy(typeof(T));
            var primaryKey = dataProxy.DbFields.Where(x => x.IsPrimaryKey).FirstOrDefault();
            bool isString = true;
            if (primaryKey.ColumnType.ToLower() == "int")
            {
                isString = false;
            }
            object[] deleteIds = ids.Split(new char[] { ',', ';' });
            if (!isString)
            {
                deleteIds = Array.ConvertAll<string, object>(ids.Split(new char[] { ',', ';' }), x => int.Parse(x));
            }
            ICriterion where = Expression.In(dataProxy.PrimaryKeyName, deleteIds);
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string sql = dataProxy.DeleteSql(ref dataParam);
            sql = string.Format(sql , " and "+ where.ToString(ref dataParam));
            int i = this.Execute(sql, dataParam);
            return i > 0;
        }
        public bool Insert<TEntity>(TEntity entity) where TEntity : class, new()
        {
            string strError = "";
            DataProxy dataProxy = new DataProxy(typeof(TEntity));
            return Insert<TEntity>(entity, dataProxy, ref strError);
        }

        public bool Insert<TEntity>(TEntity entity,ref string strError) where TEntity : class, new()
        {
            DataProxy dataProxy = new DataProxy(typeof(TEntity));
            return Insert<TEntity>(entity, dataProxy, ref strError);
        }
        public bool Insert<TEntity>(TEntity entity, DataProxy dataProxy, ref string strError)where TEntity:class,new()
        {
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string sql = dataProxy.InsertSql(this,entity,ref dataParam);
            int result = 0;
            if (dataProxy.Identifier)
            {
                result = this.Scalar(sql, dataParam).ToInt();
                if (result > 0)
                {
                    dataProxy.SetValue(entity,dataProxy.PrimaryKeyName, result);
                }
            }
            else
            {
                result = this.Execute(sql, dataParam);
            }
            return result > 0;
        }
        public bool BatchInsert<TEntity>(List<TEntity> entities, ref string strError) where TEntity : class, new()
        {
            if (entities != null && entities.Count > 0)
            {
                DataProxy dataProxy = new DataProxy(entities[0].GetType());
                foreach (var entity in entities)
                {
                    if (!this.Insert<TEntity>(entity, dataProxy, ref strError))
                    {
                        return false;
                    }
                }

            }
            return true;
        }
        public bool Update<TEntity>(TEntity entity) where TEntity : class, new()
        {
            string strError = "";
            var dataProxy = new DataProxy(typeof(TEntity));
            return Update<TEntity>(entity, dataProxy,ref strError);
        }
        public bool Update<TEntity>(TEntity entity, ref string strError) where TEntity : class, new()
        {
            var dataProxy = new DataProxy(typeof(TEntity));
            return Update<TEntity>(entity, dataProxy,ref strError);
        }
        private bool Update<TEntity>(TEntity entity, DataProxy dataProxy, ref string strError) where TEntity : class,new()
        {
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string sql = dataProxy.UpdateSql(entity, ref dataParam, ref strError);
            if (string.IsNullOrWhiteSpace(sql))
            {
                return true;
            }
            var result = this.Execute(sql, dataParam);
            if (result <= 0)
            {
                throw new Exception(entity.ToJson() + "更新失败，原因可能为未找到该数据！");
            }
          
            return result > 0;
        }

        public bool Update<TEntity>(List<TEntity> entities, ref string strError) where TEntity : class, new()
        {
            return BatchUpdate<TEntity>(entities,ref strError);
        }
        public bool BatchUpdate<TEntity>(List<TEntity> entities, ref string strError) where TEntity : class, new()
        {
            if (entities != null && entities.Count > 0)
            {
                var dataProxy = new DataProxy(entities[0].GetType());
                foreach (var entity in entities)
                {
                    if (!this.Update<TEntity>(entity, dataProxy, ref strError))
                    {
                        return false;
                    }
                }

            }
            return true;
        }
        /// <summary>
        /// 通过查询条件批量更新
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <param name="criterion"></param>
        /// <returns></returns>
        public bool Update<TEntity>(TEntity entity, ICriterion criterion) where TEntity : class, new()
        {
            var dataProxy = new DataProxy(entity.GetType());
            string strError = "";
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string sql = dataProxy.UpdateSql( entity, criterion, ref dataParam, ref strError);
            if (string.IsNullOrWhiteSpace(sql))
            {
                return true;
            }
            var result = this.Execute(sql, dataParam);
           
            return result > 0;
        }
        public bool SaveOrUpdate<T>(T entity) where T : class, new()
        {
            string strError = "";
            return SaveOrUpdate(entity,ref strError);
        }

        public bool SaveOrUpdate<T>(T entity, ref string strError) where T : class, new()
        {
            var dataProxy = new DataProxy(entity.GetType());
            return SaveOrUpdate<T>(entity,dataProxy,ref strError);
        }

        private bool SaveOrUpdate<T>(T entity, DataProxy dataProxy, ref string strError) where T : class, new()
        {
            EntityState entityState = dataProxy.IsUpdate(entity);

            if (entityState == EntityState.None)
            {
                entityState = EntityState.Add;
                if (dataProxy.IsExist(this, entity))
                {
                    entityState = EntityState.Update;
                }
            }
            if (entityState == EntityState.Add)
            {
                return this.Insert<T>(entity, dataProxy, ref strError);
            }
            else if (entityState == EntityState.Delete)
            {
                return this.Delete<T>(entity, dataProxy);
            }
            else
            {
                return this.Update<T>(entity, dataProxy, ref strError);
            }
        }
        public bool BatchSave<T>(List<T> lstData) where T : class, new()
        {
            if (lstData != null && lstData.Count > 0)
            {
                var dataProxy = new DataProxy(lstData[0].GetType());
                string strError = "";
                //List<T> insertLst = new List<T>();
                //List<T> updateLst = new List<T>();
                foreach (var entity in lstData)
                {
                    //var id = dataProxy.GetPrimaryId(entity);
                    //bool isupdate = dataProxy.IsUpdate(entity);
                    //if (!isupdate)
                    //{
                    //    T oldEntity = this.GetById<T>(id);
                    //    isupdate = oldEntity != null;
                    //}
                   bool flag= this.SaveOrUpdate<T>(entity, dataProxy, ref strError);
                    if (!flag)
                    {
                        throw new Exception(entity.ToJson()+"保存出错");
                    }
                 
                }
                
            }
            return true;
        }

        public List<T> Query<T>(ICriterion criterion) where T : class, new()
        {
           return this.Query<T>( criterion,null);
        }
        public List<T> Query<T>(string sql,ICriterion criterion) where T : class, new()
        {
            return this.Query<T>(sql, criterion,null);
        }


        public List<T> Query<T>( ICriterion criterion, Order order) where T : class, new()
        {
            var dataProxy = new DataProxy(typeof(T));
            string sql = _provider.Database.GetSelectSql(dataProxy.TableName, dataProxy.QueryFieldBuilder, dataProxy.TableAttr.IsDeleted);
            return this.Query<T>(sql, criterion,order);
        }
        public List<T> Query<T>(string sql, ICriterion criterion, Order order) where T : class, new()
        {
            List<T> lstT = new List<T>();

            if (string.IsNullOrWhiteSpace(sql))
                return null;
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string where = (criterion != null) ? criterion.ToString(ref dataParam) : "";
            if (!string.IsNullOrWhiteSpace(where))
            {
                where = " and " + where;
            }
            if (order != null)
            {
                where += " order by " + order.ToString();
            }
            sql = string.Format(sql, where);
            return _provider.Database.GetReader<T>(sql, dataParam);
        }

       public List<T> Query<T>(ICriterion criterion, Order order, int pageindex, int pageSize, ref int recordCount) where T : class, new()
        {
            var dataProxy = new DataProxy(typeof(T));
            List<T> lstT = new List<T>();
            if (pageindex > 0)
            {
                recordCount = this.RecordCount(_provider.Database.GetRecordCountSql(dataProxy.TableName), criterion,false);
                if (recordCount <= 0)
                {
                    return lstT;
                }
            }
            string sql = _provider.Database.QueryPage(string.Format(_provider.Database.GetSelectSql(dataProxy.TableName, dataProxy.QueryFieldBuilder, dataProxy.TableAttr.IsDeleted),""), new Order[] { order }, pageindex, pageSize);
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string where = (criterion != null) ? criterion.ToString(ref dataParam) : "";
            if (!string.IsNullOrWhiteSpace(where))
            {
                where = " and " + where;
            }
            sql = string.Format(sql, where);

            return _provider.Database.GetReader<T>(sql, dataParam);
        }

        public List<T> Query<T>(string hql, ICriterion criterion, Order order, int pageindex, int pageSize, ref int recordCount) where T : class, new()
        {
            List<T> lstT = new List<T>();
            if (pageindex > 0)
            {
                recordCount =this.RecordCount(hql, criterion);
                if (recordCount <= 0)
                {
                    return lstT;
                }
            }
            string sql = _provider.Database.QueryPage(hql, new Order[] { order }, pageindex, pageSize);
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string where = (criterion != null) ? criterion.ToString(ref dataParam) : "";
            if (!string.IsNullOrWhiteSpace(where))
            {
                sql = string.Format(sql, " and " + where);
            }
            else
            {
                sql = string.Format(sql, "");
            }
            sql = string.Format(sql, where);


            return _provider.Database.GetReader<T>(sql,dataParam);
        }

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="hql"></param>
        /// <param name="criterion"></param>
        /// <param name="createSql">是否需要重建Sql</param>
        /// <returns></returns>
        public int RecordCount(string hql, ICriterion criterion,bool createSql=true)
        {
            string sql = createSql?_provider.Database.RecordCount(hql): hql;
            if (string.IsNullOrWhiteSpace(sql))
                return 0;
            DataParameterCollection dataParam = new DataParameterCollection(this);
            string where = (criterion != null) ? criterion.ToString(ref dataParam) : "";
            if (!string.IsNullOrWhiteSpace(where))
            {
                where = " and " + where;
            }
            sql = string.Format(sql, where);

            return this.Scalar(sql, dataParam).ToInt();
        }



        public LigerGrid Query<T>(string hql, LigerGrid ligerGrid, ICriterion criterion) where T : class, new()
        {
            int recordCount = 0;
            var WhereExpression = ligerGrid.WhereExpression;
            if (WhereExpression != null)
            {
                criterion = Expression.And(criterion, WhereExpression);
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortOrder))
            {
                ligerGrid.sortOrder = "desc";
            }
            if (string.IsNullOrWhiteSpace(ligerGrid.sortName))
            {
                ligerGrid.sortName= EntityBase.__LastModifyDate;
            }
            Order order = (ligerGrid.sortOrder.ToLower() == "asc") ? Order.Asc(ligerGrid.sortName) : Order.Desc(ligerGrid.sortName);
            if (ligerGrid.pageSize > 0)
            {
                var result = Query<T>(hql, criterion, order, ligerGrid.pageIndex, ligerGrid.pageSize, ref recordCount);
                if (result == null)
                {
                    ligerGrid.Rows = new List<T>();
                }
                else
                {
                    ligerGrid.records = result.Count;
                    ligerGrid.Rows = result;
                }
            }
            else
            {
              var result = this.Query<T>(hql,criterion, order);
                ligerGrid.Rows = result;
                if (result != null)
                {
                    ligerGrid.records = result.Count;
                }
            }
            
            ligerGrid.Total = recordCount;
            return ligerGrid;

        }
        public LigerGrid Query<T>(LigerGrid grid, ICriterion criterion) where T : class, new()
        {
            int recordCount = 0;
            var WhereExpression = grid.WhereExpression;
            if (WhereExpression != null)
            {
                criterion = Expression.And(criterion, WhereExpression);
            }
            if (string.IsNullOrWhiteSpace(grid.sortOrder))
            {
                grid.sortOrder = "desc";
            }
            if (string.IsNullOrWhiteSpace(grid.sortName))
            {
                grid.sortName = EntityBase.__LastModifyDate;
            }
            Order order = (grid.sortOrder.ToLower() == "asc") ? Order.Asc(grid.sortName) : Order.Desc(grid.sortName);
            if (grid.pageSize > 0)
            {
                var result = Query<T>(criterion, order, grid.pageIndex, grid.pageSize, ref recordCount);
                if (result == null)
                {
                    grid.Rows = new List<T>();
                }
                else
                {
                    grid.records = result.Count;
                    grid.Rows = result;
                }
            }
            else
            {
                var result = this.Query<T>(criterion,order);
                grid.Rows = result;
                if (result != null)
                {
                    grid.records = result.Count;
                }
            }
            
            grid.Total = recordCount;
            return grid;
        }

        /// <summary>
        /// 获取ExecuteDataReader
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public IDataReader Reader(string sql, DataParameterCollection parameters)
        {
            return _provider.Database.ExecuteReader(sql,parameters.ToArray());
        }
        public object Scalar(string sql)
        {
            return _provider.Database.ExecuteScalar(sql,null);
        }
        public object Scalar(string sql, DataParameterCollection parameters)
        {
            return _provider.Database.ExecuteScalar(sql, parameters.ToArray());
        }
        public object Scalar(string sql, ICriterion criterion)
        {
            DataParameterCollection dbParameters = new DataParameterCollection(this);
           string where= criterion!=null? criterion.ToString(ref dbParameters):"";
            sql= string.Format(sql, where);
            return this.Scalar(sql,dbParameters);
        }
        public DataParameterCollection GetDbParameters()
        {
            return new DataParameterCollection(this);
        }
     
        public void Close() {

           // _provider.Database.Dispose();
            //_provider.Database.Database.CloseConnection();

        }
        public void Open()
        {
           // _provider.Database.Database.OpenConnection();
   
        }
        public void Dispose()
        {
            this.Close();
        }

        /// <summary>
        /// 禁用自增
        /// </summary>
        /// <returns></returns>
        public bool Identity_Disabled(string tableName)
        {
            string hql= _provider.Database.Identity_Disabled(tableName);
            if (!string.IsNullOrWhiteSpace(hql))
            {
                this.Execute(hql);
            }
            return true;
        }

        /// <summary>
        /// 启用自增
        /// </summary>
        /// <returns></returns>
        public bool Identity_Enable(string tableName)
        {
            string hql = _provider.Database.Identity_Enable(tableName);
            if (!string.IsNullOrWhiteSpace(hql))
            {
                this.Execute(hql);
            }
            return true;
        }

        public DbParameter[] GetParameter(List<DataParameter> Parameters)
        {
            return _provider.Database.GetParameter(Parameters);
        }
        public DataParameter GetParameter(string name, object value)
        {
            return new DataParameter(name, value) { };
        }
        public string GetParameter(string name)
        {
            return _provider.Database.GetParameter(name);
        }

        public string GetLikeParameter(string name)
        {
            return _provider.Database.GetLikeParameter(name);
        }
        /// <summary>
		/// 选择自动递增列的最大值
		/// </summary>
		/// <returns></returns>
		public int SelectIdentity(string primaryKeyName)
        {
            return _provider.Database.SelectIdentity(primaryKeyName);
        }
        /// <summary>
        /// 选择自动递增列的最大值
        /// </summary>
        /// <returns></returns>
        public string IdentitySql(string primaryKeyName)
        {
            return _provider.Database.Identity(primaryKeyName);
        }
        public DateTime Now
        {
            get
            {
                return _provider.Database.GetNow();
            }
        }
        public DbParameter MakeOutParam(string paramName, DbType DbType, int Size)
        {
            return _provider.Database.MakeOutParam(paramName, DbType, Size);
        }

        public DbParameter MakeInParam(string paramName, DbType DbType, int Size, object Value)
        {
            return _provider.Database.MakeInParam(paramName, DbType, Size, Value);
        }

        public DbParameter MakeParam(string paramName, DbType DbType, Int32 Size, ParameterDirection Direction, object Value)
        {
            return _provider.Database.MakeParam(paramName, DbType, Size, Direction, Value);
        }

        #region 获取数据库中的值
        public List<Dictionary<string, object>> GetTable(string dbName)
        {
            string sql = _provider.Database.GetTable(dbName);
            return this.Query<Dictionary<string, object>>(sql, null);
        }
        public List<Dictionary<string, object>> GetView(string dbName)
        {
            string sql = _provider.Database.GetView(dbName);
            return this.Query<Dictionary<string, object>>(sql, null);
        }
        public List<Dictionary<string, object>> GetDbColumn(string dbName, string dbServerName, bool isTable)
        {
            string sql = _provider.Database.GetDbColumn(dbName, dbServerName, isTable);
            return this.Query<Dictionary<string, object>>(sql, null);
        }

        public LigerGrid GetSource(string dbName, LigerGrid grid)
        {
            string sql = _provider.Database.GetSource(dbName);
            int reCordCount = 0;
            Order order = (string.IsNullOrWhiteSpace(grid.sortOrder) ? null : ((grid.sortOrder.ToLower() == "asc") ? Order.Asc(grid.sortName) : Order.Desc(grid.sortName)));
            var result = this.Query<Dictionary<string, object>>(sql, grid.WhereExpression, order, grid.pageIndex, grid.pageSize, ref reCordCount);
            grid.Rows = result;
            if (result != null)
            {
                grid.records = result.Count;
            }
            grid.Total = reCordCount;
            return grid;
        }

        /// <summary>
        /// 生成创建表sql
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="dbColumns"></param>
        /// <returns></returns>
        public string CreateTable(string tableName, List<DbColumnAttribute> dbColumns)
        {
            return _provider.Database.CreateTable(tableName, dbColumns);
        }

        /// <summary>
        /// 创建列
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnItem"></param>
        /// <returns></returns>
        public string AddColumn(string tableName, DbColumnAttribute columnItem)
        {
            return _provider.Database.AddColumn(tableName, columnItem);
        }
        /// <summary>
        /// 更改字段描述
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnName"></param>
        /// <param name="description"></param>
        /// <param name="isInsert"></param>
        /// <returns></returns>
        public string UpdateDescriptionSql(string tableName, string columnName, string description, bool isAdd)
        {
            return _provider.Database.UpdateDescriptionSql(tableName, columnName, description, isAdd);
        }

        /// <summary>
        /// 判断描述是否存在
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">字段名</param>
        /// <returns></returns>
        public string ExistDescriptionSql(string tableName, string columnName)
        {
            return _provider.Database.ExistDescriptionSql(tableName, columnName);
        }
        #endregion
    }
}
